#include <iostream>
#include <cstring>
#include <vector>
using namespace std;
// M表示当前状态，每个二进制位表示当前位置是否有被占据
// 状态压缩的核心:用一个数表示一个状态
// 本题由于要求的是放1*2的方块的数量
// 可以转换为求有多少种横向方块的放法
const int N = 12, M = 1 << N;
// f[i][j] 表示第i列中当前状态有几种放法
long long f[N][M];
// 表示每种状态是否没有奇数个空位置
// 奇数个空位置不能放竖状方块
bool st[M];
vector<int> status[M];
int n, m;
// 可以发现有很多冗余操作
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    while (cin >> n >> m && (n && m))
    {
        for (int i = 0; i < 1 << n; ++i)
        {
            // 先假设他没有奇数个空位
            st[i] = true;
            int cnt = 0;
            for (int j = 0; j < n; ++j)
            {
                if ((i >> j) & 1)
                {
                    if (cnt % 2)
                    {
                        st[i] = false;
                        break;
                    }
                    cnt = 0;
                }
                else
                    cnt++;
            }
            if (cnt % 2)
                st[i] = false;
        }
        // 优化:预处理每种状态的可行状态
        for (int i = 0; i < 1 << n; ++i)
        {
            status[i].clear();
            for (int j = 0; j < 1 << n; ++j)
                if ((i & j) == 0 && st[i | j])
                    status[i].push_back(j);
        }
        memset(f, 0, sizeof f);
        f[0][0] = 1;
        for (int i = 1; i <= m; ++i)
            for (int j = 0; j < (1 << n); ++j)
                for (auto k : status[j])
                    f[i][j] += f[i - 1][k];
        cout << f[m][0] << endl;
    }
    return 0;
}
